<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<link rel="Stylesheet" type="text/css" href="doc.css" />
<title>Listening to Changes</title>
</head>
<body>
<h1><a name="top">Listening to Changes</a></h1>
<p>
EMF provides an <em class="CodeName">Adapter</em> mechanism to notify listeners when
objects change.  In a transactional environment, though, we can end up reacting to changes
only to find that they are reverted when a transaction rolls back.  The EMF Transaction API
provides a different kind of listener interface, one that receives the same
<em class="CodeName">Notification</em>s, but not until the very end of a transaction:
the <a href="../javadoc/org/eclipse/emf/transaction/ResourceSetListener.html"><em class="CodeName">ResourceSetListener</em></a>.
</p><p>
The <em class="CodeName">ResourceSetListener</em> interface has two call-backs.  A
post-commit event notifies a listener of all of the changes, in a single batch, that were
committed by a transaction.  If a transaction rolls back, no event is sent because there
were no changes.  There are exceptions for changes that are not (and need not be) undone,
such as resource loading and proxy resolution.
</p><p>
The other call-back is the pre-commit event, used in the implementation of triggers, which
is <a href="triggers.html">another topic</a>.
</p>

<blockquote>
	<img src="images/listeners.png" alt="Resource Set Listener API"/><br/>
	<font size="-2">[<a href="images/listeners.svg">as SVG</a>]</font>
</blockquote>

<h2>Post-Commit Listeners</h2>

<p>
As indicated above, post-commit listeners receive <em class="CodeName">Notification</em>s
after a transaction has successfully committed the changes that they represent.  The
<em class="CodeName">resourceSetChanged()</em> call-back supplies a
<a href="../javadoc/org/eclipse/emf/transaction/ResourceSetChangeEvent.html"><em class="CodeName">ResourceSetChangeEvent</em></a>
bearing the following information:
</p>
<ul>
  <li><em class="CodeName">editingDomain</em>: the editing domain in which resource set
      the changes occurred</li>
  <li><em class="CodeName">notifications</em>: the list of notifications, in the order in
      which they were fired, indicating the changes that occurred.  These are the same
      notifications that have already been received by <em class="CodeName">Adapter</em>s</li>
  <li><em class="CodeName">transaction</em>: a reference to the <em class="CodeName">Transaction</em>
      object that was completed.  Amongst other things, this transaction has a status
      (possibly containing warnings or info messages from validation), a
      <em class="CodeName">ChangeDescription</em> summarizing the changes, and possibly
      an <em class="CodeName">OPTION_IS_UNDO_REDO_TRANSACTION</em> marker option indicating
      that the changes occurred in the undoing or redoing of a command</li>
</ul>
<p>
Listeners are attached to the editing domain.  They can declare
<a href="../javadoc/org/eclipse/emf/transaction/NotificationFilter.html"><em class="CodeName">NotificationFilter</em></a>s
that determine which notifications are of interest to them.  The available filters test
various attributes of a notification and can be combined using standard Boolean operators.
</p>
<pre class="Code">
TransactionalEditingDomain domain;

class MyListener extends <b>ResourceSetListenerImpl</b> {
    public void <b>resourceSetChanged</b>(ResourceSetChangeEvent event) {
            System.out.println("Domain " + event.<b>getEditingDomain</b>().getID() +
             " changed " + event.<b>getNotifications</b>().size() + " times");
    }
}

ResourceSetListener listener = new MyListener();

domain.<b>addResourceSetListener</b>(listener);
</pre>
<p>
The <a href="../javadoc/org/eclipse/emf/transaction/ResourceSetListenerImpl.html"><em class="CodeName">ResourceSetListenerImpl</em></a>
class is a convenient base class for listeners, providing no-op implementations of the
call-backs for selective overriding.
</p><p>
Receiving all of the notifications that occurred during the transaction in one batch is
convenient for listeners that need to analyze the entire set of changes.  Conversely,
sometimes it is more convenient to handle events one by one.  A convenient listener
abstraction for such situations is the
<a href="../javadoc/org/eclipse/emf/transaction/DemultiplexingListener.html"><em class="CodeName">DemultiplexingListener</em></a>,
class.  Simply implement the <em class="CodeName">handleNotification()</em> method to
deal with each notification individually.
</p>
<pre class="Code">
class MyDemuxedListener extends <b>DemultiplexingListener</b> {
    protected void <b>handleNotification</b>(TransactionalEditingDomain domain,
                Notification notification) {
        System.out.println("Domain " + <b>domain</b>.getID() +
            " changed: " + <b>notification</b>.getNotifier());
    }
}
</pre>
<p>
Advantages of the <em class="CodeName">ResourceSetChangedEvent</em> include:
</p>
<ul>
  <li>listeners know that the changes are permanently committed</li>
  <li>notifications can be processed efficiently as an aggregate
      <ul>
      <li>listeners don"t need to worry about dependency on "future" changes</li></ul></li>
  <li>no further changes can occur while the change event is being dispatched
      <ul>
      <li>listeners are invoked in read-only transactions, so that they can safely
          read the resource set while analyzing the changes</li></ul></li>
</ul>
<p class="Note">
Listeners need to be aware that notifications are delayed relative to the timing of the
changes.  Notifications are only received after all changes are complete.  Any given notification may
not correspond to the current state of the resource set, depending on subsequent changes.
</p>

<h2>Static Listener Registration</h2>

<p>
Attaching listeners to the editing domain at run-time works well for many applications.
However, sometimes a plug-in doesn't get a chance to attach a listener or isn't even
activated before interesting changes occur to which it needs to respond.  For these
situations, the EMF Transaction API provides the
<a href="../extension-points/org_eclipse_emf_transaction_listeners.html"><em class="CodeName">org.eclipse.emf.transaction.listeners</em></a>
extension point.  This allows applications to statically register listeners against one
or more editing domains.  The associated editing domains may be
<a href="domains.html#registry">registered</a> either statically or at run-time.  In either
case, as soon as the editing domain is instantiated in or added to the registry, its
registered listeners are created and attached.
</p>
<pre class="Code">
&lt;extension point="<b>org.eclipse.emf.transaction.listeners</b>"&gt;
    &lt;<b>listener</b> class="org.eclipse.example.MyListener"&gt;
       &lt;<b>editingDomain</b> id="org.eclipse.example.MyEditingDomain"/&gt;
    &lt;/listener&gt;
&lt;/extension&gt;
</pre>
<p>
A listener can be associated with zero or more editing domains, by ID.  In the case of
zero editing domains, the listener is implicitly attached to all editing domains that
are registered, either statically or at run-time.  Listeners cannot be registered on
editing domains that are not present in the
<a href="../javadoc/org/eclipse/emf/transaction/TransactionalEditingDomain.Registry.html"><em class="CodeName">Registry</em></a>,
even if they do have IDs.
</p>

<hr/>

<p>
<a href="https://www.eclipse.org/legal/epl-2.0/">Copyright (c) 2006, 2007 IBM Corporation and others.</a>
</p>
</body>
</html>
